
package com.lmx.persistence.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.lmx.common.constants.CommonConstants;
import com.lmx.common.context.ActionContextHolder;
import com.lmx.common.util.CommonUtil;
import com.lmx.repoDomain.tmodel.Bed;
import com.lmx.repoDomain.tmodel.Building;
import com.lmx.repoDomain.tmodel.Device;
import com.lmx.repoDomain.tmodel.DeviceTypeItem;
import com.lmx.repoDomain.tmodel.Dicttype;
import com.lmx.repoDomain.tmodel.Floor;
import com.lmx.repoDomain.tmodel.NurseGroup;
import com.lmx.repoDomain.tmodel.Room;
import net.sf.json.JSONArray;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 * 
 * 
 * @author huibati
 * @version 1.00
 */
@Service
@Scope("prototype")
public class WorkPlaceService<T> {

	private Log logger = LogFactory.getLog(this.getClass());

	@PersistenceContext
	private EntityManager em;

	@Autowired
	protected GenericService dslJpaService;
	
	@Autowired
	protected CommonService commonService;
	
	// 删除Room
	@Transactional
	public void deleteRoom(Room room) {
		room.setDelStatus((short) 1);
		room = getRoom(room);
		Floor floor = getFloorById(room.getFloor().getId());
		Building building = getBuildingById(floor.getBuilding().getId());
		floor.setRoomNum(floor.getRoomNum() - 1);
		building.setRoomNum(building.getRoomNum() - 1);
		dslJpaService.setEntityClass(Floor.class);
		dslJpaService.update(floor);
		dslJpaService.setEntityClass(Building.class);
		dslJpaService.update(building);
		dslJpaService.setEntityClass(Room.class);
		dslJpaService.update(room);
	}

	/**
	 * 获取
	 */
	public Building getBuildingById(Long id) {
		StringBuilder query=new StringBuilder("select c from Building c where c.delStatus != ?2 and c.id = ?1 ");
		List resultList = this.em.createQuery(query.toString())
				.setParameter(1, id).setParameter(2, (short) 1).getResultList();
		Building u = null;
		if (resultList.size() > 0) {
			u = (Building) resultList.get(0);
		}
		return u;
	}

	/**
	 * 获取
	 */
	public Floor getFloorById(Long id) {
		StringBuilder query=new StringBuilder("select c from Floor c where c.delStatus != ?2 and c.id = ?1 ");
		List resultList = this.em.createQuery(query.toString())
				.setParameter(1, id).setParameter(2, (short) 1).getResultList();
		Floor u = null;
		if (resultList.size() > 0) {
			u = (Floor) resultList.get(0);
		}
		return u;
	}

	/**
	 * 获取
	 */
	public Bed getBedWithDeviceNo(String seq) {
		StringBuilder query=new StringBuilder("select b from Bed b  where b.delStatus != ?1 and b.button.seq = ?2 ");
		List resultList = this.em.createQuery(query.toString())
				.setParameter(2,seq).setParameter(1, (short) 1).getResultList();
		Bed u = null;
		if (resultList.size() > 0) {
			u = (Bed) resultList.get(0);
		}
		return u;
	}
	
	/**
	 * 
	 */
	public void addFloor(Floor floor) {
		dslJpaService.setEntityClass(Floor.class);
		dslJpaService.create(floor);
	}

	/**
	 * 更改床位状态
	 */
	public void changeDedStauts(Bed bed, Dicttype bedStatus) {
		bed.setStatus(bedStatus);
		dslJpaService.setEntityClass(Bed.class);
		dslJpaService.update(bed);
	}

	/**
	 * 获取床位
	 */
	public Bed getBed(Bed bed) {
		Long id = bed.getId();
		StringBuilder query=new StringBuilder("select c from Bed c where c.delStatus != ?2 and c.id = ?1 ");
		List resultList = this.em.createQuery(query.toString())
				.setParameter(1, id).setParameter(2, (short) 1).getResultList();
		Bed u = null;
		if (resultList.size() > 0) {
			u = (Bed) resultList.get(0);
		}
		return u;
	}


	/**
	 * 获取room
	 */
	public Room getRoom(Room room) {
		Long id = room.getId();
		StringBuilder query=new StringBuilder("select c from Room c where c.delStatus != ?2 and c.id = ?1 ");
		List resultList = this.em.createQuery(query.toString())
				.setParameter(1, id).setParameter(2, (short) 1).getResultList();
		Room u = null;
		if (resultList.size() > 0) {
			u = (Room) resultList.get(0);
		}
		return u;
	}
	
	/**
	 * 获取楼层房屋名称
	 */
	public List getRoomNameByFloor(Floor floor) {
		Long id = floor.getId();
		StringBuilder query=new StringBuilder("select c.name from Room c where c.delStatus != ?2 and c.floor.id = ?1 ");
		List resultList = this.em.createQuery(query.toString())
				.setParameter(1, id).setParameter(2, (short) 1).getResultList();

		return resultList;
	}

	/**
	 * 获取床位
	 */
	public List getBedByGroup(NurseGroup group) {
		Long groupId = group.getId();
		StringBuilder query=new StringBuilder("select c from Bed c where c.delStatus != ?2 and c.group.id = ?1 ");
		List resultList = this.em.createQuery(query.toString())
				.setParameter(1, groupId).setParameter(2, (short) 1).getResultList();

		return resultList;
	}

	/**
	 * 获取bed
	 */
	public Bed getBedById(Long id) {
		StringBuilder query=new StringBuilder("select c from Bed c where c.id = ?1 and c.delStatus != ?2");
		List resultList = this.em.createQuery(query.toString())
				.setParameter(1, id).setParameter(2, (short) 1).getResultList();
		Bed u = null;
		if (resultList.size() > 0) {
			u = (Bed) resultList.get(0);
		}
		return u;
	}

	/**
	 * 获取
	 */
	public Building getBuildingByName(String name) {
		StringBuilder query=new StringBuilder("select c from Building c where c.name = ?1 and c.delStatus != ?2 and c.tenant.id=?3");
		List dataList = this.em
				.createQuery(query.toString())
				.setParameter(1, name).setParameter(2, (short) 1)
				.setParameter(3, ActionContextHolder.getContext().getTenantId()).getResultList();

		Building ct = null;
		if (dataList.size() > 0) {
			ct = (Building) dataList.get(0);
		}

		return ct;
	}

	/**
	 * 计算楼宇床位数
	 */
	public Building countBuildingBedNum(Building building) {
		JSONArray jsonArray;
		int allBedNum = 0;
		int inBedNum = 0;
		StringBuilder query=new StringBuilder("select c.status.typecode as type ,count(c.status.typecode) as num from Bed c where  c.delStatus != ?1 and c.tenant.id=?2 and c.room.floor.building.id = ?3 group by c.status.typecode ");
		List dataAllList = this.em
				.createQuery(query.toString())
				.setParameter(1, (short) 1).setParameter(2, ActionContextHolder.getContext().getTenantId())
				.setParameter(3, building.getId()).getResultList();
		if (dataAllList.size() > 0) {
			jsonArray = JSONArray.fromObject(dataAllList);// [[CommonConstants.DICTTYPE.BED_STATUS_1.label(),2],[CommonConstants.DICTTYPE.BED_STATUS_2.label(),1]]
															// [[CommonConstants.DICTTYPE.BED_STATUS_4.label(),1]]
															// bedStatusTryIn
			for (int i = 0; i < jsonArray.size(); i++) {
				String jsonObject = jsonArray.getString(i);
				jsonObject = jsonObject.replace("[", "").replace("]", "");
				if (jsonObject.contains(CommonConstants.DICTTYPE.BED_STATUS_1.label())) {
					allBedNum += Integer.parseInt(jsonObject.split(",")[1]);
				}
				if (jsonObject.contains(CommonConstants.DICTTYPE.BED_STATUS_2.label())) {
					inBedNum += Integer.parseInt(jsonObject.split(",")[1]);
					allBedNum += Integer.parseInt(jsonObject.split(",")[1]);
				}
				if (jsonObject.contains(CommonConstants.DICTTYPE.BED_STATUS_3.label())) {
					inBedNum += Integer.parseInt(jsonObject.split(",")[1]);
					allBedNum += Integer.parseInt(jsonObject.split(",")[1]);
				}
				if (jsonObject.contains(CommonConstants.DICTTYPE.BED_STATUS_4.label())) {
					inBedNum += Integer.parseInt(jsonObject.split(",")[1]);
					allBedNum += Integer.parseInt(jsonObject.split(",")[1]);
				}
			}
		}
		building.setBedAllNum(allBedNum);
		building.setBedInNum(inBedNum);
		return building;
	}

	/**
	 * 查询楼宇 所属的公共区域
	 */
	public List<Room> getPublicRoom(Building building) {
		StringBuilder query = new StringBuilder(
				"select  c  from Room c where  c.delStatus != ?1  and c.floor.building.id = ?2 and c.publicType is not null");
		List<Room> rooms = new ArrayList<>();
		rooms = this.em.createQuery(query.toString()).setParameter(1, (short) 1).setParameter(2, building.getId())
				.getResultList();
		return rooms;
	}
	
	/**
	 * 查询楼宇 所属了楼层 房间 床位
	 */
	public List<Floor> initialBuiidingData(Building building) {
		// 查询 floor room bed 数据 并对 floor room 建立 map<id,object>
		HashMap<Long, Floor> floorMap = new HashMap<>();
		StringBuilder query=new StringBuilder("select   c  from Floor c where  c.delStatus != ?1  and c.building.id = ?2 ");
		List<Floor> floors = new ArrayList<>();
		floors = this.em.createQuery(query.toString())
				.setParameter(1, (short) 1).setParameter(2, building.getId()).getResultList();
		for (Floor floor : floors) {
			if (floor != null) {
				floor.setRooms(new ArrayList<>());
				floorMap.put(floor.getId(), floor);
			}
		}
		HashMap<Long, Room> roomMap = new HashMap<>();
		query.delete(0, query.length());
		query.append("select  c  from Room c where  c.delStatus != ?1  and c.floor.building.id = ?2 ");
		List<Room> rooms = new ArrayList<>();
		rooms = this.em.createQuery(query.toString())
				.setParameter(1, (short) 1).setParameter(2, building.getId()).getResultList();
		for (Room room : rooms) {
			if (rooms != null) {
				room.setBeds(new ArrayList<>());
				roomMap.put(room.getId(), room);
			}
		}
		List<Bed> beds = new ArrayList<>();
		query.delete(0, query.length());
		query.append("select  c  from Bed c where  c.delStatus != ?1  and c.room.floor.building.id = ?2 ");
		beds = this.em.createQuery(query.toString())
				.setParameter(1, (short) 1).setParameter(2, building.getId()).getResultList();
		// 将bed塞入roommap
		for (Bed bed : beds) {
			if (bed != null) {
				Long bedRoomId=bed.getRoom().getId();
				bed.getRoom().setFloor(null);
				bed.setRoom(null);
				if (roomMap.get(bedRoomId) != null && roomMap.get(bedRoomId).getBeds() != null) {
					roomMap.get(bedRoomId).getBeds().add(bed);
				}
				//roomMap.get(bed.getRoom().getId()).getBeds().add(bed);//huibati
			}
		}
		// 将room塞入floormap
		Iterator iterRoom = roomMap.entrySet().iterator();
		while (iterRoom.hasNext()) {
			Map.Entry entry = (Map.Entry) iterRoom.next();
			Room temp = (Room) entry.getValue();
		    Long roomFloorId=temp.getFloor().getId();
		    temp.setFloor(null);
			if (floorMap.get(roomFloorId) != null && floorMap.get(roomFloorId).getRooms() != null) {
			    floorMap.get(roomFloorId).getRooms().add(temp);
			}
			//floorMap.get(temp.getFloor().getId()).getRooms().add(temp);//huibati
		}
		List<Floor> floorsTemp = new ArrayList<>();
		Iterator iterFloor = floorMap.entrySet().iterator();
		while (iterFloor.hasNext()) {
			Map.Entry entry = (Map.Entry) iterFloor.next();
			Floor temp = (Floor) entry.getValue();
			floorsTemp.add(temp);
		}
		return floorsTemp;
	}
	
	/**
	 * 验证building是否customer有关联
	 */
	public int checkBuildingRelations(Building building) {
		int flag = 0;
		Long id = building.getId();
		List levelList = new ArrayList<>();
		StringBuilder query=new StringBuilder("select c from Customer c where c.delStatus != ?1 and c.bed is not null  and c.bed.room.floor.building.id=?2 ");
		levelList = this.em.createQuery(query.toString())
				.setParameter(1, (short) 1).setParameter(2, id).getResultList();
		flag += levelList.size();
		return flag;
	}
	
	// 删除楼宇
	@Transactional
	public void deleteBuilding(Building building) {
        //删除bed
		StringBuilder query=new StringBuilder("select  c from  Bed c where c.room.floor.building.id = ?1");
		StringBuilder queryUp=new StringBuilder("update Bed u set u.delStatus = ?1 , u.lastUpdateDateTime = ?2 where u  in (:beds)");
		List<Bed> bedList = new ArrayList<>();
		bedList = this.em.createQuery(query.toString())
				.setParameter(1, building.getId()).getResultList();
		this.em.createQuery(queryUp.toString())
				.setParameter(1, (short) 1)// 已删除
				.setParameter(2, CommonUtil.getCurrTimes()).setParameter("beds", bedList).executeUpdate();
		
        //删除room
		List<Room> roomList = new ArrayList<>();
		query.delete(0, query.length());
		queryUp.delete(0, queryUp.length());
		query.append("select  c from  Room c where c.floor.building.id = ?1");
		queryUp.append("update Room u set u.delStatus = ?1 , u.lastUpdateDateTime = ?2 where u  in (:rooms)");
		roomList = this.em.createQuery(query.toString())
				.setParameter(1, building.getId()).getResultList();
		this.em.createQuery(queryUp.toString())
				.setParameter(1, (short) 1)// 已删除
				.setParameter(2, CommonUtil.getCurrTimes()).setParameter("rooms", roomList).executeUpdate();
		queryUp.delete(0, queryUp.length());
		queryUp.append("update Floor u set u.delStatus = ?1 , u.lastUpdateDateTime = ?2 where u.building.id = ?3");
        this.em.createQuery(queryUp.toString())
        .setParameter(1, (short)1)//已删除
        .setParameter(2, CommonUtil.getCurrTimes())
        .setParameter(3, building.getId())
        .executeUpdate();
		
		dslJpaService.setEntityClass(Building.class);
		dslJpaService.update(building);
	}
	
	// 创建楼宇以及楼层
	@Transactional
	public void createBuilding(Building building) {
		int upLandFloorNum = 0;
		if (building.getUpLandFloorNum() != null) {
			int addStep = 1;
			upLandFloorNum = building.getUpLandFloorNum();
			for (int i = 0; i < upLandFloorNum; i++) {
				Floor floorTemp = new Floor();
				floorTemp.setBuilding(building);
				if (building.getCreate4Flag() == 1) {// 不生成4楼
					if (i == 3) {
						addStep = 2;
					}
					if (i == 12) {
						addStep = 3;
					}
				}
				floorTemp.setName("地上" + (i + addStep) + "层");
				floorTemp.setSeq((i + 1));
				floorTemp.setDelStatus((short) 0);
				this.addFloor(floorTemp);
			}
		}
		int downLandFloorNum = 0;
		if (building.getDownLandFloorNum() != null) {
			downLandFloorNum = building.getDownLandFloorNum();
			for (int i = 0; i < downLandFloorNum; i++) {
				Floor floorTemp = new Floor();
				floorTemp.setBuilding(building);
				floorTemp.setDelStatus((short) 0);
				floorTemp.setName("地下" + (i + 1) + "层");
				floorTemp.setSeq(-(i + 1));
				this.addFloor(floorTemp);
			}
		}
	}

	// 创建楼宇以及楼层
	@Transactional
	public void updateBuilding(Building buildingTemp, Building building) {
		int upLandFloorNumOld = 0;
		int downLandFloorNumOld = 0;
		if (buildingTemp.getUpLandFloorNum() != null) {
			upLandFloorNumOld = buildingTemp.getUpLandFloorNum();
		}
		if (buildingTemp.getDownLandFloorNum() != null) {
			downLandFloorNumOld = buildingTemp.getDownLandFloorNum();
		}
		if (building.getUpLandFloorNum() > upLandFloorNumOld) {
			for (int i = 0; i < building.getUpLandFloorNum() - upLandFloorNumOld; i++) {
				Floor floorTemp = new Floor();
				floorTemp.setDelStatus((short) 0);
				floorTemp.setBuilding(building);
				floorTemp.setName("地上" + (buildingTemp.getUpLandFloorNum() + 1) + "层");
				this.addFloor(floorTemp);
			}
		} else {
			building.setUpLandFloorNum(upLandFloorNumOld);
		}
		if (building.getDownLandFloorNum() > downLandFloorNumOld) {
			for (int i = 0; i < building.getDownLandFloorNum() - downLandFloorNumOld; i++) {
				Floor floorTemp = new Floor();
				floorTemp.setDelStatus((short) 0);
				floorTemp.setBuilding(building);
				floorTemp.setName("地下" + (downLandFloorNumOld + 1) + "层");
				this.addFloor(floorTemp);
			}
		} else {
			building.setDownLandFloorNum(downLandFloorNumOld);
		}
		dslJpaService.setEntityClass(Building.class);
		dslJpaService.update(building);
	}
	
	/**
	 * 公共区域添加scanner
	 */
	public Room publicAddDevice(Room room) {
		if(room.getScanner()!=null){
			dslJpaService.setEntityClass(Device.class);
			Device scannerOld=(Device) dslJpaService.findById(room.getScanner().getId());
			scannerOld.setStatus(commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_STATUS_1.label()));// 业务状态空闲
			scannerOld.setBindStatus(commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_BIND_STATUS_2.label()));// 绑定状态空闲
			scannerOld.setLastUpdateDateTime(CommonUtil.getCurrTimes());
			dslJpaService.setEntityClass(Device.class);
			dslJpaService.update(scannerOld);
		}
		if(room.getScannerID()!=null&&!"".equals(room.getScannerID())){
			dslJpaService.setEntityClass(Device.class);
			Device scannerNew=(Device) dslJpaService.findById(Long.parseLong(room.getScannerID()));
			scannerNew.setStatus(commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_STATUS_2.label()));// 业务状态占用
			scannerNew.setBindStatus(commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_BIND_STATUS_1.label()));// 绑定状态占用
			scannerNew.setLastUpdateDateTime(CommonUtil.getCurrTimes());
			dslJpaService.setEntityClass(Device.class);
			dslJpaService.update(scannerNew);
			room.setScanner(scannerNew);
		}
		room.setLastUpdateDateTime(CommonUtil.getCurrTimes());
		dslJpaService.setEntityClass(Room.class);
		dslJpaService.update(room);
		return room;
	}
}
